using System;
using System.Data;
using System.Collections.Generic;
using System.Data.SqlClient;

using SBPweb.Data;
using SBPweb.Data.SQL2005;

using SBPweb.Common.Exceptions;

namespace SBPweb.PROvibe.Resources.Warehouse.Actor
{
	public class ActorRepository : SBPweb.Data.SQL2005.SqlRepository<Resources.Entities.Actor>
	{

		#region Private fields

		private string mDataBaseName;
		private SqlRepositoryWrapper<Resources.Entities.Actor> mWrapper;

		#endregion

		#region Constructor logic

		public ActorRepository(string databaseName)
			: base(databaseName)
		{
			this.mDataBaseName = databaseName;
			this.mWrapper = new SqlRepositoryWrapper<Resources.Entities.Actor>(this);
		}

		#endregion

        #region Public property accessors

        public SqlRepositoryWrapper<Resources.Entities.Actor> Wrapper
        {
            get
            {
                return this.mWrapper;
            }
        }

        #endregion

		#region Public methods for repository access

		#region Create

		public void Add(Resources.Entities.Actor actor)
		{
			List<SqlParameterDescriptor> parameters = new List<SqlParameterDescriptor>();

			parameters.Add(new SqlParameterDescriptor("Name", typeof(String), SqlDbType.NVarChar));
			parameters.Add(new SqlParameterDescriptor("Password", typeof(String), SqlDbType.NVarChar));
			parameters.Add(new SqlParameterDescriptor("Email", typeof(String), SqlDbType.NVarChar));
			parameters.Add(new SqlParameterDescriptor("LastActivity", typeof(DateTime), SqlDbType.DateTime));

			IInsertFactory<Resources.Entities.Actor> insertFactory = new InsertCommandFactory<Resources.Entities.Actor>("PROvibe_CreateActor", parameters);

			try
			{
				base.Add(insertFactory, actor);

				Entity.SetActionState(actor, EntityActionState.Added);
				Entity.SetTransactionState(actor, EntityTransactionState.Saved);
			}
			catch (SqlException ex)
			{
				ExceptionHandler.HandleSqlException(ex);
			}
		}

		#endregion

		#region Read

		public List<Resources.Entities.Actor> GetActors()
		{
			ISelectionFactory<NullableIdentity> selectionFactory = new ReadAllCommandFactory("PROvibe_ReadActor");

			try
			{
				NullableIdentity nullableIdentity = new NullableIdentity();
				return base.Find(selectionFactory, new EntityColumnFactory<Resources.Entities.Actor>(), nullableIdentity);
			}
			catch (SqlException ex)
			{
				ExceptionHandler.HandleSqlException(ex);
			}

			return new List<Resources.Entities.Actor>();
		}

		public Resources.Entities.Actor GetActorById(Int32 id)
		{
			ISelectionFactory<List<KeyValuePair<string, object>>> selectionFactory = new ReadByParameteredCommandFactory("PROvibe_ReadActor");

			List<KeyValuePair<string, object>> pars = new List<KeyValuePair<string, object>>();
			pars.Add(new KeyValuePair<string,object>("Id", id));

			try
			{
				return base.FindOne(selectionFactory, new EntityColumnFactory<Resources.Entities.Actor>(), pars);
			}
			catch (SqlException ex)
			{
				ExceptionHandler.HandleSqlException(ex);
			}

			return new Resources.Entities.Actor();
		}

		public Resources.Entities.Actor GetActorByName(String name)
		{
			ISelectionFactory<List<KeyValuePair<string, object>>> selectionFactory = new ReadByParameteredCommandFactory("PROvibe_ReadActor");

			List<KeyValuePair<string, object>> pars = new List<KeyValuePair<string, object>>();
			pars.Add(new KeyValuePair<string, object>("Name", name));

			try
			{
				return base.FindOne(selectionFactory, new EntityColumnFactory<Resources.Entities.Actor>(), pars);
			}
			catch (SqlException ex)
			{
				ExceptionHandler.HandleSqlException(ex);
			}

			return new Resources.Entities.Actor();
		}

		#endregion

		#region Update

		public void Update(Resources.Entities.Actor actor)
		{
			List<SqlParameterDescriptor> parameters = new List<SqlParameterDescriptor>();

			parameters.Add(new SqlParameterDescriptor("Id", typeof(Int32), SqlDbType.Int));
			parameters.Add(new SqlParameterDescriptor("Name", typeof(String), SqlDbType.NVarChar));
			parameters.Add(new SqlParameterDescriptor("Password", typeof(String), SqlDbType.NVarChar));
			parameters.Add(new SqlParameterDescriptor("Email", typeof(String), SqlDbType.NVarChar));
			parameters.Add(new SqlParameterDescriptor("LastActivity", typeof(DateTime), SqlDbType.DateTime));
			
			IUpdateFactory<Resources.Entities.Actor> updateFactory = new UpdateCommandFactory<Resources.Entities.Actor>("PROvibe_UpdateActor", parameters);

			try
			{
				base.Update(updateFactory, actor);

				Entity.SetActionState(actor, EntityActionState.Modified);
				Entity.SetTransactionState(actor, EntityTransactionState.Saved);
			}
			catch (SqlException ex)
			{
				ExceptionHandler.HandleSqlException(ex);
			}
		}

		#endregion

		#region Delete

		public void Remove(Int32 id)
		{
			IDeleteFactory<Int32> deleteFactory = new DeleteCommandFactory("PROvibe_DeleteActor");

			try
			{
				base.Remove(deleteFactory, id);
			}
			catch (SqlException ex)
			{
				ExceptionHandler.HandleSqlException(ex);
			}
		}

		#endregion

		#endregion

		#region Public methods for transaction handling

		public override void Commit(Resources.Entities.Actor actor)
		{
			if (actor.TransactionState != EntityTransactionState.Saved)
			{
				ExceptionHandler.HandleException(new Exception("Unsaved entites cannot be commited!"));
			}
			else
			{
				base.Commit(actor);
				Entity.SetTransactionState(actor, EntityTransactionState.Committed);
			}
		}

		public override void Rollback(Resources.Entities.Actor actor)
		{
			base.Rollback(actor);

			Entity.SetTransactionState(actor, EntityTransactionState.Rollbacked);
		}

		#endregion

	}
}
